package com.lmj.utils;


import com.nimbusds.jose.*;
import com.nimbusds.jose.crypto.MACSigner;
import com.nimbusds.jose.crypto.MACVerifier;
import com.nimbusds.jwt.JWTClaimsSet;
import com.nimbusds.jwt.SignedJWT;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.text.ParseException;
import java.util.Date;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

@Component
public class TokenUtil {

    @Resource
    RedisUtil redisUtil;

    /**
     * 创建秘钥
     */
    private static final byte[] SECRET = "qngChengBoYa-realtimeWuIngWangJiaQiZhangYv".getBytes();

    /**
     * 生成token
     * @param userPhone
     * @return {@link String}
     */
    public String buildToken(String userPhone) {

        try {
            /**
             * 1.创建一个32-byte的密匙
             */
            MACSigner macSigner = new MACSigner(SECRET);
            /**
             * 2. 建立payload 载体
             */
            JWTClaimsSet claimsSet = new JWTClaimsSet.Builder()
                    .subject("login")
                    .claim("user",userPhone)
                    .issueTime(new Date())
                    .build();

            /**
             * 3. 建立签名
             */
            SignedJWT signedJWT = new SignedJWT(new JWSHeader(JWSAlgorithm.HS256), claimsSet);
            signedJWT.sign(macSigner);

            /**
             * 4. 生成token
             */
            String token = signedJWT.serialize();
            redisUtil.setExpire(userPhone, 30);
            return token;
        } catch (KeyLengthException e) {
            e.printStackTrace();
        } catch (JOSEException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 校验token
     * @param token
     * @return
     */
    public boolean verifyToken(String token) {

        try {
            SignedJWT jwt = SignedJWT.parse(token);
            JWSVerifier verifier = new MACVerifier(SECRET);

            /**
             * 校验是否有效
             */
            if (!jwt.verify(verifier)) {
                return false;
            }
            /**
             * 获取载体中的数据
             */
            String account = (String) jwt.getJWTClaimsSet().getClaim("ACCOUNT");
            // 是否有数据
            if (Objects.isNull(account)){
                return false;
            }

        } catch (ParseException e) {
            e.printStackTrace();
        } catch (JOSEException e) {
            e.printStackTrace();
        }
        return false;
    }

    public void setToken(String userPhone, String token) {
        redisUtil.set(userPhone, token, 30);
    }
}
